const dropAreaEle = document.querySelector('.drop-area'); // 拖拽区域
const dropTextEle = document.querySelector('.drop-area-text'); // 拖拽区域提示
const imgsContainer = document.querySelector('.image-preview-container'); // 预览容器
const maskEle = document.querySelector('.mask'); // 遮罩
const progressTxtEle = document.querySelector('.progress-bar-text'); // 进度条文字
const progressValueEle = document.querySelector('.progress-bar-value'); // 进度条进度
const helperEle = document.querySelector('.drop-area-helper'); // 错误提示
const abortBtn = document.querySelector('.btn-abort'); //Abort按钮
const clearBtn = document.querySelector('.btn-clear'); //Clear按钮
const fileInput = document.getElementById('file'); //点击上传
const maskCloseEle = document.querySelector('.mask-close'); //遮罩关闭按钮

const FAILED_COLOR = '#ff5858';
const IMAGE_MIME_REGEX = /^image\/(jpe?g|gif|png)$/i;

// 阻止默认行为
function preventDefaults(e) {
   e.preventDefault();
   e.stopPropagation();
}
['dragenter', 'dragover', 'dragleave', 'drop'].forEach((eventName) => {
   dropAreaEle.addEventListener(eventName, preventDefaults, false);
   document.body.addEventListener(eventName, preventDefaults, false);
});

// 切换目标区域的高亮状态
function highlight(e) {
   if (!dropAreaEle.classList.contains('highlight')) {
      dropAreaEle.classList.add('highlight');
   }
}
function unhighlight(e) {
   if (dropAreaEle.classList.contains('highlight')) {
      dropAreaEle.classList.remove('highlight');
   }
}
['dragenter', 'dragover'].forEach((eventName) => {
   dropAreaEle.addEventListener(eventName, highlight, false);
});
['dragleave', 'mouseleave'].forEach((eventName) => {
   dropAreaEle.addEventListener(eventName, unhighlight, false);
});

// 清空预览内容
const handleClearPreview = () => {
   imgsContainer.innerHTML = '';
};

// 重置进度条
const handleResetProgress = () => {
   progressValueEle.style.width = 0;
   progressValueEle.style.background = 'rgb(70, 184, 204)';
   progressTxtEle.style.color = 'rgb(70, 184, 204)';
   progressTxtEle.innerText = '开始上传...';
};

// 清空所有内容
clearBtn.addEventListener('click', () => {
   handleClearPreview();
   handleResetProgress();
   maskEle.style.visibility = 'hidden';
   dropTextEle.style.display = 'flex';
   maskCloseEle.style.visibility = 'hidden';
});

/*----------------------------- 上传方式 -----------------------------*/
// 1. 拖拽上传
dropAreaEle.addEventListener(
   'drop',
   (e) => {
      const dt = e.dataTransfer;
      const files = [...dt.files];
      handleUploadOneByOne(files);
   },
   false
);

// 2. 点击上传
fileInput.addEventListener('change', () => {
   let files = [...fileInput.files];
   handleUploadOneByOne(files);
});

// 上传前验证
const beforeUpload = (files) => {
   // 数量判断
   if (files.length > 12) {
      genHelperTxt(helperEle, '一次最多只能上传12张图片');
      return false;
   }
   // 类型判断
   if (!files.every((file) => IMAGE_MIME_REGEX.test(file.type))) {
      genHelperTxt(helperEle, '只能上传图片文件');
      return false;
   }

   // 大小判断
   const maxSize = 1024 * 1024 * 5;
   if (!files.every((file) => file.size <= maxSize)) {
      genHelperTxt(helperEle, `文件大小不能超过${maxSize / 1024 / 1024}M`);
      return false;
   }

   handleClearPreview();
   // 隐藏最初的提示词
   dropTextEle.style.display = 'none';
   return true;
};

// 上传处理(一次性同时处理多个)
const handleMutiUpload = (files) => {
   if (!beforeUpload(files)) return;

   // 创建图片预览元素
   files.forEach(createPreviewItem);

   // 执行上传
   uploadFile(files, {
      onUploadStart: () => {
         handleResetProgress();
         maskEle.style.visibility = 'visible';
         maskCloseEle.style.visibility = 'hidden';
         setDisabled(abortBtn, false);
         setDisabled(clearBtn, true);
      },
      onUploadProgress: (value) => {
         progressTxtEle.innerText = `正在上传：${value}`;
         progressValueEle.style.width = value;
      },
      onUploadSuccess: () => {
         progressTxtEle.innerHTML = '上传成功，请等待服务器处理...';
      },
      onUploadEnd: () => {
         setDisabled(abortBtn, true);
      },
      onSuccess: () => {
         progressTxtEle.innerHTML = '√ 成功上传至服务器。可继续拖拽进行上传';
         maskCloseEle.style.visibility = 'visible';
         setDisabled(clearBtn, false);
      },
      onError: (err) => {
         progressValueEle.style.background = FAILED_COLOR;
         progressTxtEle.style.color = FAILED_COLOR;
         progressTxtEle.innerHTML = `✘ 上传失败  ${err}`;
         maskCloseEle.style.visibility = 'visible';
         setDisabled(clearBtn, false);
      },
      abortHandler: abortBtn,
      onAbort: () => {
         progressValueEle.style.background = FAILED_COLOR;
         progressTxtEle.style.color = FAILED_COLOR;
         progressTxtEle.innerHTML = `✘ 上传被强制中止`;
         maskCloseEle.style.visibility = 'visible';
         setDisabled(abortBtn, true);
         setDisabled(clearBtn, false);
      },
   });
};

// 上传处理(逐个上传)
const handleUploadOneByOne = async (files) => {
   if (!beforeUpload(files)) return;

   // 创建图片预览元素
   let fileList = [];
   for (let i = 0; i < files.length; i++) {
      fileList.push({
         file: files[i],
         ele: createPreviewItem(files[i]),
         index: String(i),
      });
   }

   setDisabled(clearBtn, true);
   const uploadQueue = [];
   while (fileList.length > 0) {
      while (uploadQueue.length < 3 && fileList.length > 0) {
         const item = fileList.shift();
         const promise = createUploadPromise(item.file, item.ele, item.index);
         uploadQueue.push({
            promise,
            index: item.index,
         });
     
      }

      await Promise.race(uploadQueue.map((item) => item.promise)).then(
         (index) => {
            const idx = uploadQueue.findIndex((item) => item.index === index);
            uploadQueue.splice(idx, 1);
         }
      );
   }

   // 上传结束
   await Promise.all(uploadQueue.map((item) => item.promise)).then(()=>{
      setDisabled(clearBtn, false);
   })
};

// 创建预览元素
function createPreviewItem(file) {
   const div = document.createElement('div');
   const img = document.createElement('img');
   img.src = URL.createObjectURL(file);
   div.classList.add('preview-item', 'shadow');
   div.append(img);

   const span = document.createElement('span');
   span.innerText = file.name;
   span.title = file.name;
   div.append(span);

   imgsContainer.append(div);

   return div;
}

// 关闭遮罩
maskCloseEle.addEventListener('click', () => {
   maskEle.style.visibility = 'hidden';
   maskCloseEle.style.visibility = 'hidden';
});

const createProgressEles = (parent) => {
   const div = document.createElement('div');
   div.classList.add('preview-item-mask');

   const blockEle = document.createElement('div');
   blockEle.classList.add('progress-block');
   div.append(blockEle);

   const textEle = document.createElement('div');
   textEle.classList.add('progress-text');
   div.append(textEle);

   parent.append(div);

   return [blockEle, textEle];
};

const createUploadPromise = (image, ele, index) => {
   let progressBlcok = null;
   let progressText = null;
   return uploadFile(image, {
      index,
      onUploadStart: () => {
         const [blockEle, textEle] = createProgressEles(ele);
         progressBlcok = blockEle;
         progressText = textEle;
      },
      onUploadProgress: (value) => {
         progressBlcok.style.height = value;
         progressText.innerText = value;
      },
      onUploadSuccess: () => {
         progressText.innerText = '请稍后';
      },
      onUploadEnd: () => {},
      onSuccess: () => {
         progressText.innerText = '√';
      },
      onError: (err) => {
         progressText.innerText = '✘';
         progressText.style.color = FAILED_COLOR;
         progressBlcok.style.background = FAILED_COLOR;
      },
      abortHandler: abortBtn,
      onAbort: () => {
         progressText.innerText = '';
         progressText.style.color = FAILED_COLOR;
         progressBlcok.style.background = FAILED_COLOR;
      },
   });
};
